<template>
  <div class="cesium-viewer-wapper">
    <div id="cesium-viewer" />
    <d-tooltip-box v-model:visible="tooltipVisible" :content="tooltipContent" :position="tooltipPosition" />
    <FeaturePropertiesBar :properties="featureProps" :title="featureTitle" :visible="featurePropsVisible" />
    <viewerSettingSidebar top="29em" :viewerSource="viewerSource" />
    <div class="tool-box-top-left">
      <!-- <div class="select-box-wrapper"><select-box :options="flyOptions" style="margin-right: 0;" /></div> -->
      <div class="select-box-wrapper"><a-checkbox v-model:checked="viewModel.flyOver">FlyOver</a-checkbox></div>
      <div class="select-box-wrapper"><a-checkbox v-model:checked="viewModel.colorByHeight">Color by height</a-checkbox></div>
      <!-- <div class="select-box-wrapper"><SliderBar v-model:value="height" :min="-1000" :max="1000" :step="10">height</SliderBar></div> -->
      <div id="legend-items">
        <div>
          <span class="legend-colorBlock" style="background: #7f3b08"></span>
          0 to 5 meters
        </div>
        <div>
          <span class="legend-colorBlock" style="background: #c66a0b"></span>
          5 to 10 meters
        </div>
        <div>
          <span class="legend-colorBlock" style="background: #f8b057"></span>
          10 to 25 meters
        </div>
        <div>
          <span class="legend-colorBlock" style="background: #fce6c8"></span>
          25 to 50 meters
        </div>
        <div>
          <span class="legend-colorBlock" style="background: #e0e2ee"></span>
          50 to 100 meters
        </div>
        <div>
          <span class="legend-colorBlock" style="background: #aaa2cc"></span>
          100 to 200 meters
        </div>
        <div>
          <span class="legend-colorBlock" style="background: #664797"></span>
          200 to 300 meters
        </div>
        <div>
          <span class="legend-colorBlock" style="background: #2d004b"></span>
          Above 300 meters
        </div>
      </div>
    </div>
    <GlobeRotater showTime :viewerSource="viewerSource" />
    <MousePosition show :viewerSource="viewerSource" />
  </div>
</template>

<script>
import * as Cesium from '@cesiumjs';
import FlyOver from './FlyOver';
import { defineComponent, ref, reactive, watch, toRaw } from 'vue';
import { SelectBox, SliderBar, DTooltip, DTooltipBox, FeaturePropertiesBar } from '@components/widgets';
import { MousePosition, viewerSettingSidebar, GlobeRotater } from '@g3x/g3v/ui';
import { G3V } from '@g3x';
import { viewerMixin } from '@mixins';
// import merge from '@g3x/utils/merge';

const $g3vOptions = {
  defaultViewRectangle: G3V.defaultViews.global.china.rectangle,
  viewers: [
    {
      dom: 'cesium-viewer',
      name: 'viewer1',
      title: 'viewer#01',
      viewer: {
        imagery: { type: 'arcgisImagery', options: { brightness: 1, show: true } },
        imageryProvider: null,
        terrain: { type: 'default', options: { requestVertexNormals: true, requestWaterMask: true } },
        terrainProvider: null,
        shadows: false,
        scene3DOnly: true,
        // sceneMode: Cesium.SceneMode.SCENE2D,
        animation: false
      },
      layers: [],
      tileset: [],
      globe: {
        depthTestAgainstTerrain: true,
        enableLighting: true //启用以太阳为光源的地球
      },
      bottomContainer: false,
      navigation: {
        defaultResetView: null //flyHome
      },
      shortcutAction: false,
      hideLayers: false
    }
  ]
};

// http://www1.nyc.gov/site/doitt/initiatives/3d-building.page
export default defineComponent({
  name: 'buildings', // 城市3d建筑模型
  mixins: [viewerMixin],
  components: { SelectBox, SliderBar, viewerSettingSidebar, GlobeRotater, MousePosition, DTooltip, DTooltipBox, FeaturePropertiesBar },
  props: {},
  setup() {
    return {tileset: null};
  },
  data() {
    return {
      viewModel: { flyOver: false, colorByHeight: false },
      tooltipContent: 'safasdfasdf',
      tooltipPosition: [600, 500],
      tooltipVisible: false,
      featureProps: {},
      featureTitle: '',
      featurePropsVisible: false
    };
  },
  computed: {},
  watch: {},
  methods: {
    g3vOptionsGet(original) {
      // const g3vOptions = merge($g3vOptions, true);
      return $g3vOptions;
    },
    onViewerInited() {
      console.log('buildings onViewerInited');
      const vm = this;
      const { viewer, g3vViewer } = vm;
      const { scene, canvas } = viewer;
      const globe = scene.globe;

      // Set the initial camera view to look at Manhattan
      var initialPosition = Cesium.Cartesian3.fromDegrees(-74.01881302800248, 40.69114333714821, 753);
      var initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees(21.27879878293835, -21.34390550872461, 0.0716951918898415);
      viewer.scene.camera.setView({
        destination: initialPosition,
        orientation: initialOrientation,
        endTransform: Cesium.Matrix4.IDENTITY
      });

      // Load the NYC buildings tileset
      var tileset = new Cesium.Cesium3DTileset({
        url: Cesium.IonResource.fromAssetId(75343)
      });
      viewer.scene.primitives.add(tileset);

      vm.tileset = tileset;

      // =======================================================================
      // Information about the currently selected feature

      function FeatureSelect(highlightColor) {
        this.feature = undefined;
        this.originalColor = new Cesium.Color();
        this.set = function(feature) {
          if (feature !== this.feature) {
            if (this.feature) {
              this.feature.color = Cesium.Color.clone(this.originalColor, this.feature.color);
            }
            this.feature = feature;
            if (feature) {
              Cesium.Color.clone(feature.color, this.originalColor);
              feature.color = Cesium.Color.clone(highlightColor, feature.color);
            }
          }
        };
      }

      var selected = new FeatureSelect(Cesium.Color.LIME);
      var highlighted = new FeatureSelect(Cesium.Color.YELLOW);

      // Get default left click handler for when a feature is not picked on left click
      var defaultClickHandler = viewer.screenSpaceEventHandler.getInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
      var defaultDblClickHandler = viewer.screenSpaceEventHandler.getInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
      var defaultMoveHandler = viewer.screenSpaceEventHandler.getInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);

      // =======================================================================
      // MOUSE_MOVE
      // Color a feature yellow on hover.
      viewer.screenSpaceEventHandler.setInputAction(evt => {
        var pickedFeature = scene.pick(evt.endPosition);
        if (!pickedFeature || pickedFeature !== selected.feature) {
          highlighted.set(pickedFeature);
        }

        let tooltipVisible = !!pickedFeature;
        if (tooltipVisible) {
          vm.tooltipPosition = [evt.endPosition.x, canvas.clientHeight - evt.endPosition.y];
          var name = pickedFeature.getProperty('BIN');
          vm.tooltipContent = name;
        }

        vm.tooltipVisible = tooltipVisible;

        defaultMoveHandler && defaultMoveHandler(evt);
      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

      // =======================================================================
      // LEFT_CLICK
      // Color a feature on selection and show metadata in the InfoBox.
      viewer.screenSpaceEventHandler.setInputAction(evt => {
        var pickedFeature = scene.pick(evt.position);
        // if (!Cesium.defined(pickedFeature)) {
        //   defaultClickHandler(evt);
        // }
        highlighted.set(undefined);
        selected.set(pickedFeature);

        vm.updateFeatureInfo(pickedFeature);

        defaultClickHandler && defaultClickHandler(evt);
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

      viewer.screenSpaceEventHandler.setInputAction(e => {
        var t = scene.pick(e.position);

        defaultDblClickHandler && defaultDblClickHandler(e);
        if (!Cesium.defined(t)) return;

        const lon = parseFloat(t.getProperty('Longitude'));
        const lat = parseFloat(t.getProperty('Latitude'));
        var height = parseFloat(t.getProperty('Height'));
        var degrees = Cesium.Cartesian3.fromDegrees(lon, lat, height / 2);
        var c = Math.min(Math.max(2 * height, 100), 250);

        viewer.camera.flyToBoundingSphere(new Cesium.BoundingSphere(degrees, c), {
          duration: 1.5
        });
      }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
    },
    initEffects() {
      const vm = this;
      const { viewer, g3vViewer } = vm;
      const { scene, canvas } = viewer;

      const flyOver = new FlyOver(scene);

      watch(
        () => vm.viewModel.flyOver,
        val => {
          flyOver.enabled = val;
        }
      );
      watch(
        () => vm.viewModel.colorByHeight,
        val => {
          vm.colorByHeight(val);
        }
      );
    },
    updateFeatureInfo(feature) {
      const vm = this;
      if (!feature) {
        vm.featureProps = undefined;
        vm.featureTitle = '';
        vm.featurePropsVisible = false;
        return;
      }
      const batchTable = feature._content.batchTable;
      const properties = batchTable._properties;

      vm.featureTitle = feature.getProperty('BIN');

      vm.featureProps = {};
      Object.keys(properties).forEach(name => {
        vm.featureProps[name] = batchTable.getProperty(feature._batchId, name);
      });

      vm.featurePropsVisible = true;
    },
    colorByHeight(enable) {
      console.log('colorByHeight', enable);

      const vm = this;

      if (enable) {
        const styleByHeight = new Cesium.Cesium3DTileStyle({
          color: {
            conditions: [
              ['${Height} < 5', "color('#7f3b08')"],
              ['${Height} < 10', "color('#c66a0b')"],
              ['${Height} < 25', "color('#f8b057')"],
              ['${Height} < 50', "color('#fce6c8')"],
              ['${Height} < 100', "color('#e0e2ee')"],
              ['${Height} < 200', "color('#aaa2cc')"],
              ['${Height} < 300', "color('#664797')"],
              ['true', "color('#2d004b')"]
            ]
          },
          // show : '${Height} > 100',
        });
        vm.tileset.style = styleByHeight
      } else {
        const styleDefault = new Cesium.Cesium3DTileStyle({
          color: {
            conditions: [['${brokenRelation} === true', "color('red')"], ['true', "color('white')"]]
          }
        });
        vm.tileset.style = undefined
      }
    }
  }
});
</script>

<style lang="less">
.cesium-viewer-wapper {
  .tool-box-top-left {
    min-width: 15em;
  }

  #legend-items {
    display: flex;
    flex-direction: column;
    background-color: rgba(0, 0, 0, 0.75);
    padding: 10px 20px;

    & > div {
      display: flex;
      align-items: center;
      .legend-colorBlock {
        width: 12px;
        height: 12px;
        margin-right: 9px;
      }
    }
  }
}
</style>
